Import Necessary Libraries


In [1]:
from time import time
import numpy as np
import os
import sys,getopt,os
import matplotlib.pyplot as plt
import pdb
import random
import auxiliary_functions
reload(auxiliary_functions)
import auxiliary_functions
from auxiliary_functions import *


#-------Adjust MatPlotLib Properties for this iPython Notebook-------
%matplotlib inline
#--------------------------------------------------------------------

Initializations


In [2]:
N = 32                                             # Codeword length
K = 16                                              # Messageword lengt
max_e = 32                                          # Maximum number of erasures to consider
min_e = 4                                           # Minimum number of erasures to consider
step_e = 8                                          # Erasure step

d_v = 4                                             # Degree of variable nodes
d_c = 8                                             # Degree of check nodes
d_max = 1                                           # Maximum (Mean in case of exponential distribution) delay of the edges in the parity check matrix. A value of 0 represents standard belief propagation
no_avg_itrs = 40                                    # Number of times a random noisy vector is generated for decoding
max_decoding_itr = 10000                              # Maximum number of iterations that the decodng algorithm is run after which a failure is declared
ensemble_size = 1                                   # The number of random graphs that will be considered in the simulations

track_deg_one_flag = 0                              # If equal to 1, the code tracks the number of degree one check nodes in the residual graph.
e0_range = range(min_e,max_e,step_e)                # Number of erased bits

final_BER_wo_Delay = np.zeros([1,len(e0_range)])    # The average bit error rate at the end of decoding for the delay-less decoding
final_BER_synchronous = np.zeros([1,len(e0_range)]) # The average bit error rate at the end of decoding for synchronous decoding
final_BER_w_Delay = np.zeros([1,len(e0_range)])     # The average bit error rate at the end of decoding for the delayed decoding
    
final_PER_w_Delay = np.zeros([1,len(e0_range)])     # The average block error rate at the end of decoding for the delayed decoding
final_PER_wo_Delay = np.zeros([1,len(e0_range)])    # The average block error rate at the end of decoding for the delay-less decoding
final_PER_synchronous = np.zeros([1,len(e0_range)]) # The average block error rate at the end of decoding for synchronous decoding
    
decoding_itr_w_Delay = np.zeros([1,len(e0_range)])      # The average number of decoding iterations for synchronous decoding
decoding_itr_wo_Delay = np.zeros([1,len(e0_range)])     # The average number of decoding iterations for the delay-less decoding
decoding_itr_synchronous = np.zeros([1,len(e0_range)])  # The average number of decoding iterations for the delayed decoding
    
decoding_time_wo_Delay = np.zeros([1,len(e0_range)])    # The average decoding time for synchronous decoding with uniform mean-delays    
decoding_time_synchronous = np.zeros([1,len(e0_range)]) # The average decoding time for the synchrnous decoder
decoding_time_w_Delay = np.zeros([1,len(e0_range)])     # The average decoding time for synchronous decoding

if not os.path.isdir('./Results'):                      # Create a folder if not already exists
    os.makedirs('./Results')

Construct the Parity Check Graph


In [3]:
H,D_0,E0 = bipartite_graph(N,N-K,d_v,d_c,1,np.zeros([2,2]))
H,D_orig,E = bipartite_graph(N,N-K,d_v,d_c,d_max,H)
D_0 = np.sign(D_0) 
#print E

Perform Error Decoding

First, we pick an erasure from the range of erasures we want to simulate. Then, we generate no_avg_itrs random erroneous codewords to simulate the performance of the decoders for that particular erasure value.

Asynchronous Decoding


In [6]:
itr_error = 0
for e0 in e0_range:                
    for itr in range(0,no_avg_itrs):
        #-------------------Generate the Noisy Input Vector------------------------
        ind_e = range(0,N)
        random.shuffle(ind_e)
        x_init = np.zeros([1,N])            # The all-zero codeword is assumed
        x_init[0,ind_e[0:e0]] = -1         # The noisy codeword
        #-------------------------------------------------------------------------
        
        #------------------------Asynchronous Decoding-----------------------------
        err,decoding_itr,decoding_time,deg_one_w_delay_vs_itr = asynchronous_decoder(H,D_0,D_orig,E,x_init,max_decoding_itr,N,K,track_deg_one_flag,0,d_max)
        #-------------------------------------------------------------------------
        
        #--------Update BER, BER, and other performance measurement metrics-------
        final_BER_w_Delay[0,itr_error] = final_BER_w_Delay[0,itr_error] + err
        final_PER_w_Delay[0,itr_error] = final_PER_w_Delay[0,itr_error] + np.sign(err)
        decoding_itr_w_Delay[0,itr_error] = decoding_itr_w_Delay[0,itr_error] + decoding_itr
        decoding_time_w_Delay[0,itr_error] = decoding_time_w_Delay[0,itr_error] + decoding_time
        #-------------------------------------------------------------------------
        
    itr_error = itr_error + 1
    
final_BER_w_Delay = np.divide(final_BER_w_Delay,float(N*no_avg_itrs))
final_PER_w_Delay = np.divide(final_PER_w_Delay,float(no_avg_itrs))
decoding_itr_w_Delay = np.divide(decoding_itr_w_Delay,float(no_avg_itrs))
decoding_time_w_Delay= np.divide(decoding_time_w_Delay,float(no_avg_itrs))

Jittered Asynchronous Decoding


In [7]:
itr_error = 0
for e0 in e0_range:                
    for itr in range(0,no_avg_itrs):
        #-------------------Generate the Noisy Input Vector------------------------
        ind_e = range(0,N)
        random.shuffle(ind_e)
        x_init = np.zeros([1,N])            # The all-zero codeword is assumed
        x_init[0,ind_e[0:e0]] = -1         # The noisy codeword
        #-------------------------------------------------------------------------
        
        #--------------------Jittered Asynchronous Decoding-----------------------
        err,decoding_itr,decoding_time,deg_one_wo_delay_vs_itr = asynchronous_decoder(H,D_0,D_orig,E,x_init,max_decoding_itr,N,K,track_deg_one_flag,1,d_max)
        #-------------------------------------------------------------------------
        
        #--------Update BER, BER, and other performance measurement metrics-------
        final_BER_wo_Delay[0,itr_error] = final_BER_wo_Delay[0,itr_error] + err
        final_PER_wo_Delay[0,itr_error] = final_PER_wo_Delay[0,itr_error] + np.sign(err)
        decoding_itr_wo_Delay[0,itr_error] = decoding_itr_wo_Delay[0,itr_error] + decoding_itr
        decoding_time_wo_Delay[0,itr_error] = decoding_time_wo_Delay[0,itr_error] + decoding_time
        #-------------------------------------------------------------------------
        
    itr_error = itr_error + 1
    
final_BER_wo_Delay = np.divide(final_BER_wo_Delay,float(N*no_avg_itrs))
final_PER_wo_Delay = np.divide(final_PER_wo_Delay,float(no_avg_itrs))
decoding_itr_wo_Delay = np.divide(decoding_itr_wo_Delay,float(no_avg_itrs))
decoding_time_wo_Delay= np.divide(decoding_time_wo_Delay,float(no_avg_itrs))

Synchronous Decoding


In [13]:
itr_error = 0
for e0 in e0_range:                
    for itr in range(0,no_avg_itrs):
        #-------------------Generate the Noisy Input Vector------------------------
        ind_e = range(0,N)
        random.shuffle(ind_e)
        x_init = np.zeros([1,N])            # The all-zero codeword is assumed
        x_init[0,ind_e[0:e0]] = -1         # The noisy codeword
        #-------------------------------------------------------------------------
        
        #pdb.set_trace()
        
        #--------------------Jittered Asynchronous Decoding-----------------------
        err,decoding_itr,decoding_time,deg_one_sync_vs_itr = synchronous_decoder(H,x_init,E,N,K,max_decoding_itr,track_deg_one_flag)
        #-------------------------------------------------------------------------
        
        
        #--------Update BER, BER, and other performance measurement metrics-------
        final_BER_synchronous[0,itr_error] = final_BER_synchronous[0,itr_error] + err
        final_PER_synchronous[0,itr_error] = final_PER_synchronous[0,itr_error] + np.sign(err)
        decoding_itr_synchronous[0,itr_error] = decoding_itr_synchronous[0,itr_error] + decoding_itr
        decoding_time_synchronous[0,itr_error] = decoding_time_synchronous[0,itr_error] + decoding_time
        #-------------------------------------------------------------------------
        
    itr_error = itr_error + 1
    
final_BER_synchronous = np.divide(final_BER_synchronous,float(N*no_avg_itrs))
final_PER_synchronous = np.divide(final_PER_synchronous,float(no_avg_itrs))
decoding_itr_synchronous = np.divide(decoding_itr_synchronous,float(no_avg_itrs))
decoding_time_synchronous = np.divide(decoding_time_synchronous,float(no_avg_itrs))

Plot Results

Compare BER


In [14]:
e0_prob = np.divide(np.array(e0_range),float(N))
plt.grid(True)

plt.plot(e0_prob,final_BER_synchronous[0,:],'bs-',label='Standard BP',linewidth=3)
plt.plot(e0_prob,final_BER_wo_Delay[0,:],'ro--',label='Asynchronous BP, Jittered',linewidth=3)
plt.plot(e0_prob,final_BER_w_Delay[0,:],'g.-',label='Asynchronous BP',linewidth=3)
plt.rcParams['figure.figsize'] = (12.0, 8.0)
plt.legend(framealpha=0.5)
plt.xlabel("$ \epsilon $")
plt.ylabel('BER')
plt.show()


Compare number of decoding iterations


In [15]:
e0_prob = np.divide(np.array(e0_range),float(N))
plt.grid(True)

plt.plot(e0_prob,decoding_itr_synchronous[0,:],'bs-',label='Standard BP',linewidth=3)
plt.plot(e0_prob,decoding_itr_wo_Delay[0,:],'ro--',label='Asynchronous BP, Jittered',linewidth=3)
plt.plot(e0_prob,decoding_itr_w_Delay[0,:],'g.-',label='Asynchronous BP',linewidth=3)
plt.rcParams['figure.figsize'] = (12.0, 8.0)
plt.legend(framealpha=0.5)
plt.xlabel("$ \epsilon $")
plt.ylabel('# Decoding Iterations')
plt.show()


Compare decoder's time


In [16]:
e0_prob = np.divide(np.array(e0_range),float(N))
plt.grid(True)

plt.plot(e0_range,decoding_time_synchronous[0,:],'bs-',label='Standard BP',linewidth=3)
plt.plot(e0_range,decoding_time_wo_Delay[0,:],'ro--',label='Asynchronous BP, Jittered',linewidth=3)
plt.plot(e0_range,decoding_time_w_Delay [0,:],'g.-',label='Asynchronous BP',linewidth=3)
plt.rcParams['figure.figsize'] = (12.0, 8.0)
plt.legend(framealpha=0.5)
plt.xlabel("$ \epsilon $")
plt.ylabel("Decoder's Time (s) ")
plt.show()



In [ ]: